package com.metaverse.backend.service;

import com.alibaba.fastjson.JSONObject;
import com.metaverse.backend.domain.RoomLog;
import com.metaverse.backend.domain.User;
import com.metaverse.backend.douyin.PlayerDataDTO;
import com.metaverse.backend.douyin.RoomDataDTO;
import com.metaverse.backend.dto.RoomProgressUpdateDTO;
import com.metaverse.backend.enums.GiftAttributeEnum;
import com.metaverse.backend.exception.BusinessException;
import com.metaverse.backend.security.JwtTokenUtil;
import com.metaverse.backend.utils.ApplicationContextUtil;
import com.metaverse.backend.utils.SnowflakeIdWorker;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Service;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;

/**
 * 房间数据环境
 */
@Data
@Slf4j
@AllArgsConstructor
@Service
public class RoomDataContext {

    private JwtTokenUtil jwtTokenUtil;

    private Map<String, RoomDataManage> roomDataManageMap;

    private DouYinApiService douYinApiService;

    private RoundHelper roundHelper;


    private SnowflakeIdWorker snowflakeIdWorker;

    private RoomLogService roomLogService;


    /**
     * 获取当前支持的房间数据管理
     *
     *
     */
    private RoomDataManage getRoomDataManagerByVersion(String gameVersion) {
        RoomDataManage roomDataManage = null;
        for (RoomDataManage item : roomDataManageMap.values()) {
            if (item.supportVersion(gameVersion)) {
                roomDataManage = item;
                break;
            }
        }

        if (roomDataManage == null) {
            throw new IllegalArgumentException("不支持游戏版本[" + gameVersion + "]");
        }


        return roomDataManage;
    }


    /**
     * 获取当前支持的房间数据管理
     *
     *
     */
    private RoomDataManage getRoomDataManagerByRoundId(String roundId) {
        RoomLog roomLog = roomLogService.findLastByRoundId(roundId);
        if (roomLog == null) {
            log.warn("查找管理对象失败，未找到对局信息：" + roundId);
            throw new IllegalArgumentException("对局记录不存在");
        }

        return this.getRoomDataManagerByVersion(roomLog.getGameVersion());

    }


    /**
     * 开始游戏
     *
     *
     */
    public RoomDataDTO start(User user, String roomId, String gameVersion) {

        RoomDataManage roomDataManage = getRoomDataManagerByVersion(gameVersion);

//        String roundId = roundHelper.currentRoundId(roomId);

//        if (StringUtils.isEmpty(roundId)) {
//            //产生新的局号 开始游戏
//            roundId  = String.valueOf(snowflakeIdWorker.nextId());
//            roundHelper.setCurrentRoundId(roomId, roundId);
//        }

        //启动推送数据
        if (ApplicationContextUtil.isRunProd()) {
            douYinApiService.tryStartAll(roomId, 3);
        } else {
            log.warn(">>>>>>>>>>测试环境已跳过任务推送！！！！！！！！！！" + roomId);
        }


        //检查游戏状态
//        RoomDataDTO roomDataDTO = roomDataManage.getRoomDataDTO(roomId, roundId);

//        if(roomDataDTO == null || roomDataDTO.isGameEnd()){
        //游戏结束产生新的局号 新游戏
        String roundId = String.valueOf(snowflakeIdWorker.nextId());
        roundHelper.setCurrentRoundId(roomId, roundId);
        List<RoomProgressUpdateDTO> list = new ArrayList<>();
        for (int i = 1; i <= 12; i++) {
            RoomProgressUpdateDTO roomProgressUpdateDTO = new RoomProgressUpdateDTO();
            roomProgressUpdateDTO.setLocation(i);
            roomProgressUpdateDTO.setBaseBloodVolume(100);
            roomProgressUpdateDTO.setShieldsVolume(100);
            roomProgressUpdateDTO.setSuperMultiplier(1);
            roomProgressUpdateDTO.setSuperThreshold(100);
            roomProgressUpdateDTO.setBaseArmor(100);
            roomProgressUpdateDTO.setCurrentBlood(100);
            roomProgressUpdateDTO.setCurrentShield(100);
            roomProgressUpdateDTO.setCurrentArmor(100);
            roomProgressUpdateDTO.setIsLock(false);
            roomProgressUpdateDTO.setIsDestroy(false);
            roomProgressUpdateDTO.setPlayerCount(0);
            list.add(roomProgressUpdateDTO);
        }
        RoomDataDTO roomDataDTO = roomDataManage.updateRoomDataProgress(roomId, list);
        roomDataDTO.setProgress(list);
        roomLogService.add(roomId, roundId, gameVersion, user);
//        }else{
//            //断线重连
//            List<PlayerDataDTO>  playerDataList =  roomDataManage.getAllPlayerData(roomId);
//            roomDataDTO.setPlayerDataList(playerDataList);
//            RoomLog log =  roomLogService.findByRoomId( user.getOpenid(), roomId,roundId);
//            if (log!=null){
//                long instant = log.getCreatedAt().atZone(ZoneId.systemDefault()).toInstant().toEpochMilli();
//                roomDataDTO.setStartTime(instant);
//            }
//        }
//        roomDataDTO.setLevelCongfig(GiftLevelEnum.getGiftAttributeDTOMap());
        roomDataDTO.setGiftGiftAttributeCongfig(GiftAttributeEnum.getGiftAttributeMap());
        log.info("开始游戏:{}, 游戏版本：{}", JSONObject.toJSONString(roomDataDTO), gameVersion);
        return roomDataDTO;


    }

    /**
     * 重试
     *
     * @param user
     * @param roomId
     * @return
     */
    public RoomDataDTO reconnect(User user, String roomId) {
        String roundId = roundHelper.currentRoundId(roomId);
        if (StringUtils.isEmpty(roundId)) {
            return null;
        }
        RoomDataManage roomDataManage = null;
        try {
            roomDataManage = getRoomDataManagerByRoundId(roundId);
        } catch (Exception e) {
            return null;
        }

        //检查游戏状态
        RoomDataDTO roomDataDTO = roomDataManage.getRoomDataDTO(roomId, roundId);

        if (roomDataDTO == null || roomDataDTO.isGameEnd()) {
            return null;
        }

        //启动推送数据
        if (ApplicationContextUtil.isRunProd()) {
            douYinApiService.tryStartAll(roomId, 3);
        } else {
            log.warn(">>>>>>>>>>重连，测试环境已跳过任务推送！！！！！！！！！！" + roomId);
        }

        //断线重连
        List<PlayerDataDTO> playerDataList = roomDataManage.getAllPlayerData(roomId);
        roomDataDTO.setPlayerDataList(playerDataList);
//        roomDataDTO.setLevelCongfig(GiftLevelEnum.getGiftAttributeDTOMap());
        roomDataDTO.setGiftGiftAttributeCongfig(GiftAttributeEnum.getGiftAttributeMap());
        log.info("断线重连数据：{}", roomDataDTO);
        return roomDataDTO;
    }


    /**
     * 一局结束
     *
     * @param user
     * @param roomId
     * @return
     */
    public List<PlayerDataDTO> end(User user, String roomId) {

        try {
            String roundId = roundHelper.currentRoundId(roomId);
            RoomDataManage roomDataManage = getRoomDataManagerByRoundId(roundId);


            //游戏结束
            RoomDataDTO roomDataDTO = roomDataManage.endGame(roomId);

            //把本局数据全部拿出来进行排名 给出前20名;
            List<PlayerDataDTO> rankList = roomDataManage.sortAndGetRankList(roomId, roomDataDTO);

            //持久化数据
            roomDataManage.persistPlayerData(roomId);


//            douYinApiService.reportGameInfo(user.getOpenid(), roomDataDTO, rankList);

            log.info("游戏结束处理，房间ID:{}, 排行版数据：{}", roomId, rankList);
            return rankList;
        } catch (Exception e) {
            return new ArrayList<>();
        }

    }
    /**
     *
     */

    public void updatePlayerProgress(String openid, int ballCount, String roomId, String roundIdd) {
        String roundId = roundHelper.currentRoundId(roomId);
        RoomDataManage roomDataManage = getRoomDataManagerByRoundId(roundId);
        roomDataManage.getPlayerVariation(openid, ballCount, roomId, roundIdd);
    }


    /**
     * 推送消息
     *
     * @param roomId
     * @param reqData
     * @param msg_type
     */
    public void pushMsg(String roomId, String reqData, String msg_type) {
        String roundId = roundHelper.currentRoundId(roomId);
        RoomDataManage roomDataManage = getRoomDataManagerByRoundId(roundId);
        roomDataManage.pushMsg(roomId, reqData, msg_type);
    }

    /**
     * 获取房间信息
     *
     * @param roomId
     * @param roundId
     * @return
     */
    public RoomDataDTO getRoomDataDTO(String roomId, String roundId) {
        RoomDataManage roomDataManage = getRoomDataManagerByRoundId(roundId);
        return roomDataManage.getRoomDataDTO(roomId, roundId);
    }


    /**
     * 读取新消息
     *
     * @return
     */
    public RoomDataDTO readNewMsg(String roomId, String roundId) {
        RoomDataManage roomDataManage = getRoomDataManagerByRoundId(roundId);
        RoomDataDTO roomDataDTO = roomDataManage.getRoomDataDTO(roomId, roundId);

        if (roomDataDTO == null) {
            throw new BusinessException("游戏未开始，请重新开始游戏");
        }

        //附加新的数据消息
        roomDataManage.appendChangedMsgData(roomDataDTO);

        return roomDataDTO;
    }


    /**
     * 更新游戏进度
     *
     * @param roomId
     * @return
     */
    public RoomDataDTO updateRoomDataProgress(String roomId, List<RoomProgressUpdateDTO> roomProgressUpdateDTOList) {
        String roundId = roundHelper.currentRoundId(roomId);
        RoomDataManage roomDataManage = getRoomDataManagerByRoundId(roundId);
        return roomDataManage.updateRoomDataProgress(roomId, roomProgressUpdateDTOList);
    }
}
